﻿#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTextCodec>
#include <QTime>
#include <QWidget>

#include <QStandardItemModel>

//更新说明：MCU升级|FPGA升级 -> 更新F210的固件。

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //获取文件路径
    FilePath=QDir::currentPath();
    //设置隐藏项
    ui->btn_left_sql_dlbox->setVisible(false);
    ui->btn_left_cfg_dlbox->setVisible(false);
    ui->btn_left_bat_f210->setVisible(false);
    ui->btn_left_disp_f210->setVisible(false);
    ui->btn_left_mtsn_dlbox->setVisible(true);
    ui->btn_title_dlbox->setVisible(true);
    ui->btn_title_f210->setVisible(true);
    ui->progressBar_dlbox->setVisible(false);
    ui->cbx_dev_dlbox->setVisible(false);
    Config_Param_Init();
    Menu_Init();
    Param_Init();

    Gui_Init();
    Left_Widgt_Init();
    LeftWidget_TitleBtn_Init();

    ui->btn_ContactUs->setVisible(false);

    //定时器
    timer = new QTimer; //定时扫描和更新串口
    connect(timer,&QTimer::timeout,this,&MainWindow::Check_Port_Status_Each_Time);//实时更新端口号
    timer->start(TIMER_RECV_TIME_OUT);

	Port_F210_Port_Init();
	Port_Dlbox_Port_Init();
	Port_f316_Port_Init();
	Port_dl8000_Port_Init();

#if 0
    // 当前版本需隐藏F210升级
    ui->btn_upg->setHidden(true);
    ui->cbx_upg->setHidden(true);
    // 解决发布时切换到其它界面再切回F210会出现升级按钮问题
    ui->btn_title_f316->setHidden(true);
    ui->btn_left_loop_f316->setHidden(true);
    ui->btn_title_dlbox->setHidden(true);
    ui->btn_left_mtsn_dlbox->setHidden(true);
    ui->btn_title_dl8000->setHidden(true);
    ui->btn_left_dl8000->setHidden(true);
#endif
#if 0
    // 检测端口
    Check_Port_Status_Each_Time();
    // f210
    Check_null_device_detected(portStringList, "CH340", ui->te_prin);
    Check_null_device_detected(portStringList, "CH340", ui->te_prin_disp_f210);
    // dl400
    Check_null_device_detected(portStringList, "Prolific", ui->te_prin_dlbox);
#endif
    
}

MainWindow::~MainWindow()
{
    if(timer->isActive())
        timer->stop();
    if(SyncTimer->isActive())
        SyncTimer->stop();
    if(RecvTimer->isActive())
        RecvTimer->stop();
    if(WaitTimer->isActive())
        WaitTimer->stop();
    //
    if(SerialThread->isRunning())
    {
        SerialThread->quit();
        SerialThread->wait();
    }
    if(ComThread_disp_f210->isRunning())
    {
        ComThread_disp_f210->quit();
        ComThread_disp_f210->wait();
    }

    delete CfgFile;
    delete ui;
}

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    switch (event->type()) {
    case QEvent::HoverEnter:{
        if(watched == ui->btn_title_f210)
        {
            LeftWidget_BtnTitle_SetIcon_Move(ui->btn_title_f210, &HoverStu_f210);
        }
        else if(watched == ui->btn_title_dlbox)
        {
            LeftWidget_BtnTitle_SetIcon_Move(ui->btn_title_dlbox, &HoverStu_dlbox);
        }
        else if(watched == ui->btn_title_f316)
        {
            LeftWidget_BtnTitle_SetIcon_Move(ui->btn_title_f316, &HoverStu_f316);
        }
        else if(watched == ui->btn_title_dl8000)
        {
            LeftWidget_BtnTitle_SetIcon_Move(ui->btn_title_dl8000, &HoverStu_dl8000);
        }
        break;
    }
    case QEvent::HoverLeave:{
        if(watched == ui->btn_title_f210)
        {
            LeftWidget_BtnTitle_SetIcon_Leave(ui->btn_title_f210, &HoverStu_f210);
        }
        else if(watched == ui->btn_title_dlbox)
        {
            LeftWidget_BtnTitle_SetIcon_Leave(ui->btn_title_dlbox, &HoverStu_dlbox);
        }
        else if(watched == ui->btn_title_f316)
        {
            LeftWidget_BtnTitle_SetIcon_Leave(ui->btn_title_f316, &HoverStu_f316);
        }
        else if(watched == ui->btn_title_dl8000)
        {
            LeftWidget_BtnTitle_SetIcon_Leave(ui->btn_title_dl8000, &HoverStu_dl8000);
        }
        break;
    }
    case QEvent::MouseButtonRelease:{
        if(watched == ui->btn_title_f210)
        {
            LeftWidget_BtnTitle_SetIcon_Release(ui->btn_title_f210, LeftBtns_f210, &HoverStu_f210);
            ui->btn_left_mtsn_f210->setChecked(true);
            on_btn_left_mtsn_f210_clicked();
        }
        else if(watched == ui->btn_title_dlbox)
        {
            LeftWidget_BtnTitle_SetIcon_Release(ui->btn_title_dlbox, LeftBtns_dlbox, &HoverStu_dlbox);
            ui->btn_left_mtsn_dlbox->setChecked(true);
            on_btn_left_mtsn_dlbox_clicked();
        }
        else if(watched == ui->btn_title_f316)
        {
            LeftWidget_BtnTitle_SetIcon_Release(ui->btn_title_f316, LeftBtns_f316, &HoverStu_f316);
            ui->btn_left_loop_f316->setChecked(true);
            on_btn_left_loop_f316_clicked();
        }
        else if(watched == ui->btn_title_dl8000)
        {
            LeftWidget_BtnTitle_SetIcon_Release(ui->btn_title_dl8000, LeftBtns_dl8000, &HoverStu_dl8000);
            ui->btn_left_dl8000->setChecked(true);
        }
        break;
    }
    default:
        break;
    }
    if (watched == ui->wdg_title)
    {
        if (event->type() == QEvent::MouseButtonDblClick)
        {
            on_btn_menu_max_clicked();
        }
    }
    return QWidget::eventFilter(watched, event);
}

/*---------------------------------------------------------------------------
函数名：mouseMoveEvent
功能：鼠标移动事件函数，在该函数内实现对窗口的拖动功能
只有在鼠标左键按下的情况下才能对窗口进行拖动
---------------------------------------------------------------------------*/
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if (MaxStu) // 如果当前是最大化，则不允许移动
        return;

    if ((event->buttons() & Qt::LeftButton) && m_bMouseLftBtnPressed) // 是否按下鼠标左键
    {
        QPoint ptTemp = event->globalPos();      // 当前鼠标全局位置
        ptTemp = ptTemp - m_ptMouseLatestPos;    // 计算移动变量
        ptTemp = ptTemp + pos();                 // 窗口原始位置（pos()） + 鼠标移动变量（ptemp） = 最终窗口位置
        move(ptTemp);                            // 移动窗口到新的位置

        m_ptMouseLatestPos = event->globalPos();    // 记录当前鼠标按下的位置
    }
}


/*---------------------------------------------------------------------------
函数名：mousePressEvent
功能：鼠标按键按下事件函数，在函数内判断是否可以拖动该窗口
只有在标题栏区域内按下鼠标左键才可以拖动当前窗口
---------------------------------------------------------------------------*/
void MainWindow::mousePressEvent(QMouseEvent *event)
{
    this->setFocus();

    // 只有在标题栏区域内按下鼠标左键且当前窗口不是最大化的情况下才可以拖动
    if (Qt::LeftButton == event->button() && (0 == (Qt::WindowMaximized & this->windowState())))
    {
        // 只有在标题栏区域内按下鼠标左键才可以进行拖动操作
        if (ui->wdg_title->geometry().contains(event->pos()))
        {
            m_ptMouseLatestPos = event->globalPos();       // 记录鼠标按下的位置
            m_bMouseLftBtnPressed = true;   // 标记鼠标为按下状态
            event->ignore();
        }
    }
}


/*---------------------------------------------------------------------------
函数名：mouseReleaseEvent
功能：鼠标按键抬起事件函数，在该函数内将取消窗口的可拖动操作
只有鼠标左键抬起的情况下才认为要结束拖动
---------------------------------------------------------------------------*/
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
    if (Qt::LeftButton == event->button())
    {
        m_bMouseLftBtnPressed = false;
        clickPos=event->pos();
    }

}

bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    if (MaxStu) // 如果当前是最大化，则不允许移动
        return false;

    MSG* msg = (MSG*)message;
    switch(msg->message)
    {
    case WM_NCHITTEST:
        int xPos = QCursor().pos().rx() - this->frameGeometry().x();
        int yPos = QCursor().pos().ry() - this->frameGeometry().y();
        if (xPos < boundaryWidth && yPos<boundaryWidth)                    // 左上角
            *result = HTTOPLEFT;
        else if (xPos>=width ()-boundaryWidth&&yPos<boundaryWidth)          // 右上角
            *result = HTTOPRIGHT;
        else if (xPos<boundaryWidth&&yPos>=height ()-boundaryWidth)         // 左下角
            *result = HTBOTTOMLEFT;
        else if (xPos>=width ()-boundaryWidth&&yPos>=height ()-boundaryWidth)// 右下角
            *result = HTBOTTOMRIGHT;
        else if (xPos < boundaryWidth)                                     // 左边
            *result =  HTLEFT;
        else if (xPos>=width ()-boundaryWidth)                              // 右边
            *result = HTRIGHT;
        else if (yPos<boundaryWidth)                                       // 上边
            *result = HTTOP;
        else if (yPos>=height ()-boundaryWidth)                             // 下边
            *result = HTBOTTOM;
        else              // 其他部分不做处理，返回 false，留给其他事件处理器处理
           return false;
        return true;
    }
    return false;         // 此处返回 false，留给其他事件处理器处理

}

void MainWindow::getQssColor(const QString &qss, const QString &flag, QString &color)
{
    int index = qss.indexOf(flag);
    if (index >= 0) {
        color = qss.mid(index + flag.length(), 7);
    }
}

void MainWindow::getQssColor(const QString &qss, QString &textColor, QString &panelColor,
                          QString &borderColor, QString &normalColorStart, QString &normalColorEnd,
                          QString &darkColorStart, QString &darkColorEnd, QString &highColor)
{
    getQssColor(qss, "TextColor:", textColor);
    getQssColor(qss, "PanelColor:", panelColor);
    getQssColor(qss, "BorderColor:", borderColor);
    getQssColor(qss, "NormalColorStart:", normalColorStart);
    getQssColor(qss, "NormalColorEnd:", normalColorEnd);
    getQssColor(qss, "DarkColorStart:", darkColorStart);
    getQssColor(qss, "DarkColorEnd:", darkColorEnd);
    getQssColor(qss, "HighColor:", highColor);
}

void MainWindow::Config_Param_Init()
{
    LangureStu = 0;

    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));

    //读取ini
    QSettings *LangureRead = new QSettings(FilePath+"/cfg/config.ini",QSettings::IniFormat);
    LangureStu = LangureRead->value("MainMenu/Language").toInt();
    delete LangureRead;

    CfgFile = new QSettings(FilePath+"/cfg/config.ini",QSettings::IniFormat);
    CfgFile_Dlbox = new QSettings(FilePath+"/cfg/dlbox_config.ini",QSettings::IniFormat);
}

void MainWindow::Param_Init()
{
    m_bMouseLftBtnPressed = false;
    boundaryWidth = 4;

    VersFileName = UPG_FILE_NAME_APP3;
    FpgaFileName = UPG_FILE_NAME_FPGA;

    PortStu = PORT_STU_NULL;
    LastPortStu = PORT_STU_NULL;
    ModelStu = 1;
    ModelStu_dlbox = 0;
    RecvStu = false;
    PortVer = 0;
    MaxStu = 0;
    UpgStu = 0;

    AllFileSize = 0;
    RecvSize = 0;
    TimeOutCnt = 0;
    WaitOutCnt = 0;
    SendOutCnt = 0;
    PageCnt = 0;
    RecvCnt = 0;

    RecvStr.clear();
    RecvData.resize(524);
    RecvData.clear();
    RecvMtSN.resize(524);
    RecvMtSN.clear();
    SendData.clear();
    ReadFileName.clear();
    BurnFileName.clear();
	
    RecvStr_dlbox.clear();

    IconsLeft.clear();
    IconsLeft << 0x00 << 0x00 << 0x00 << 0x00 << 0x00 << 0x00 << 0x00;

    LeftBtns.clear();
    LeftBtns << 0x00;

    DefMtSN.clear();
    ConnectStu = 0;
    ConnectStu_dlbox = 0;
    ConnectStu_disp_f210 = 0;
    CPortName.clear();
    CPortName_disp_f210.clear();
    PortList_f210.clear();
    PortList_disp_f210.clear();
    HoverStu_f210 = true;
    //
    DefMtSN = Get_MtSN_From_Dev_File();

    //dlbox
    HoverStu_dlbox = true;
    OutCnt_dlbox = 0;
    SendAddr_dlbox = 0;
    PortList_dlbox.clear();
    CPortName_dlbox.clear();
	
	//f316
	HoverStu_f316 = true;
    SendCnt_f316 = 0;
    PageCnt_f316 = 0;
    PortStu_f316 = 0;
    TimeOutCnt_f316 = 0;
    WaitOutCnt_f316 = 0;

    //dl8000
    HoverStu_dl8000 = true;
    ModelStu_dl8000 = 0;
    PageCnt_dl8000 = 0;
    ConnStu_dl8000 = 0;
    PortStu_dl8000 = 0;
    LastPortStu_dl8000 = 0;
    RecvStu_dl8000 = true;
    TimeOutCnt_dl8000 = 0;
    WaitOutCnt_dl8000 = 0;
    SendOutCnt_dl8000 = 0;
	PortStu_dl8000 = PORT_STU_NULL;
	
	RecvMtSN_dl8000.clear();
}

QByteArray MainWindow::Get_MtSN_From_Dev_File()
{
    QByteArray DefMtSN;
    DefMtSN.clear();

    //ROM_FILE_NAME_IX
    //ROM_FILE_NAME_IXR
    //ROM_FILE_NAME_IXSMAX
    //ROM_FILE_NAME_I8
    //ROM_FILE_NAME_I8P
    //ROM_FILE_NAME_I8P_A
    //ROM_FILE_NAME_I11
    //ROM_FILE_NAME_I11P
    //ROM_FILE_NAME_I12
    //ROM_FILE_NAME_I12PM
    //ROM_FILE_NAME_I13
    QStringList DevFileNames;
    DevFileNames.append(ROM_FILE_NAME_IX);
    DevFileNames.append(ROM_FILE_NAME_IXR);
    DevFileNames.append(ROM_FILE_NAME_IXSMAX);
    DevFileNames.append(ROM_FILE_NAME_I8);
    DevFileNames.append(ROM_FILE_NAME_I8P);
    DevFileNames.append(ROM_FILE_NAME_I8P_A);
    DevFileNames.append(ROM_FILE_NAME_I11);
    DevFileNames.append(ROM_FILE_NAME_I11P);
    DevFileNames.append(ROM_FILE_NAME_I12);
    DevFileNames.append(ROM_FILE_NAME_I12PM);
    DevFileNames.append(ROM_FILE_NAME_I13);

    int OffserAddr[DevFileNames.size()];
    int icnt = 0;
    OffserAddr[icnt++] = 0x0000120C;
    OffserAddr[icnt++] = 0x00003F00;
    OffserAddr[icnt++] = 0x0000120C;
    OffserAddr[icnt++] = 0x00003A37;
    OffserAddr[icnt++] = 0x00003A37;
    OffserAddr[icnt++] = 0x00003A37;
    OffserAddr[icnt++] = 0x00001540;
    OffserAddr[icnt++] = 0x00001480;
    OffserAddr[icnt++] = 0x00003DA7;
    OffserAddr[icnt++] = 0x00003DA7;
    OffserAddr[icnt++] = 0x000000A7;

    for(icnt = 0;icnt<DevFileNames.count();icnt++)
    {
        QFile DevFile(DevFileNames.at(icnt));
        if(!DevFile.open(QIODevice::ReadOnly))
        {
            DefMtSN.append("                                            ");
            DevFile.close();
            continue;
        }
        if(DevFile.size() != 16384)
        {
            DefMtSN.append("                                            ");
            DevFile.close();
            continue;
        }

        DevFile.seek(OffserAddr[icnt]);
        char MtsnBuff[44];
        DevFile.read(MtsnBuff,44);
        for(int jcnt = 0;jcnt<44;jcnt++)
        {
            DefMtSN.append(MtsnBuff[jcnt]);
        }

        DevFile.close();
    }

    return DefMtSN;
}

#include <QDesktopWidget>
void MainWindow::Gui_Init()
{
    QDesktopWidget *desktopWidget = QApplication::desktop(); //获取程序的桌面信息
    QScreen *myScreen = QGuiApplication::primaryScreen();
    QRect screenRect = desktopWidget->screenGeometry(); //QGuiApplication::screens();
    int screenX = screenRect.width();//屏幕的宽度
    int screenY = screenRect.height();//屏幕的高度
    double scaleX = screenX/1920.0;//此时屏幕宽对比正常1920的倍数
    double scaleY = screenY/1080.0;//此时屏幕高对比正常1080的倍数
    //然后按照倍数去移动位置以及调整大小
    ui->centralwidget->move(150*scaleX, 300*scaleY);//(150,300)是1920*1080屏幕上的坐标
    ui->centralwidget->resize(1500*scaleX, 900*scaleY);//1500和900是1920*1080屏幕上的宽和高
    this->resize(1500*scaleX, 900*scaleY);

    ui->wdg_title_option->isHidden();

    //设置系统图标
    QIcon TitleIcon(":/image/256ico.ico");
    this->setWindowIcon(TitleIcon);
    //实例阴影shadow
    QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
    //设置阴影距离
    shadow->setOffset(1, 1);
    //设置阴影颜色
    shadow->setColor(QColor("#444444"));
    //设置阴影圆角
    shadow->setBlurRadius(30);
    //给嵌套QWidget设置阴影
    ui->centralwidget->setGraphicsEffect(shadow);
    //给垂直布局器设置边距(此步很重要, 设置宽度为阴影的宽度)
    //ui->centralwidget->setContentsMargins(4,4,4,4);//设置为0时，就看不到边框的阴影
    //设置无边框
    this->setWindowFlags(
    Qt::Window \
    |Qt::FramelessWindowHint\
    |Qt::WindowMinimizeButtonHint\
    |Qt::WindowMaximizeButtonHint);
    //设置图标
    QImage *img=new QImage; //新建一个image对象
    img->load(":/image/32ico.png");
    ui->lbl_ico->setPixmap(QPixmap::fromImage(*img));

    QIcon MinIcon(":/image/min.png");
    ui->btn_menu_min->setIcon(MinIcon);
    ui->btn_menu_min->setFlat(true);
    MaxIcon = new QIcon(":/image/max.png");
    ui->btn_menu_max->setIcon(*MaxIcon);
    ui->btn_menu_max->setFlat(true);
    QIcon CloseIcon(":/image/close.png");
    ui->btn_menu_close->setIcon(CloseIcon);
    ui->btn_menu_close->setFlat(true);

    QIcon HelpIcon(":/image/menu.png");
    ui->btn_menu_menu->setIcon(HelpIcon);
    ui->btn_menu_menu->setFlat(true);
    ui->btn_menu_menu->setStyleSheet("QPushButton::menu-indicator{image:none;width:0px;}");
	
	ui->btn_menu_drive->setFlat(true);
	ui->btn_menu_drive->setStyleSheet("QPushButton::menu-indicator{image:none;width:0px;}");
	ui->btn_menu_langure->setFlat(true);

    int fontId = QFontDatabase::addApplicationFont(FilePath + "/cfg/msyh.ttc");
    if(fontId >= 0)
    {
        QString msyh = QFontDatabase::applicationFontFamilies(fontId).at(0);
        AppFont.setFamily(msyh);
    }
    AppFont.setPixelSize(15);
    QApplication::setFont(AppFont);
    AppFont.setPixelSize(20);
    ui->lbl_title->setFont(AppFont);

    //关联事件过滤器用于双击放大
    ui->wdg_title->installEventFilter(this);

    ui->wdg->setProperty("form", "body");
    ui->wdg_title->setProperty("form", "title");
    ui->wdg_left->setProperty("flag", "left");
    ui->wdg_body->setProperty("form", "body");
    ui->pg_color->setProperty("form", "body");
    ui->pg_disp_f210->setProperty("form", "body");
    ui->pg_mtsn_dlbox->setProperty("form", "body");
    ui->pg_mtsn_dl8000->setProperty("form", "body");
    ui->wdg_bottom->setProperty("form", "bottom");

    //设置白色底色边框
    QPalette bgpal = palette();
    bgpal.setColor (QPalette::Background, QColor(245, 245, 245, 255));
    setPalette(bgpal);

    //失去焦点
    setFocus(Qt::ActiveWindowFocusReason);

    Body_Load_Style(":/qss/flatgray.css");
    Title_Load_Style(":/qss/blacksoft.css");
    //
    hexEdit = new QHexMonitor(this);
    ui->vlyt_right->addWidget(hexEdit);
    hexEdit_dlbox = new QHexMonitor(this);
    ui->vlyt_right_dlbox->addWidget(hexEdit_dlbox);
    hexEdit_code_f210 = new QHexMonitor(this);
    ui->vlyt_right_disp_f210->addWidget(hexEdit_code_f210);
    //控件设置文字
    App_Langure_to_Change();
    Btn_Link_Langure_to_Set(ui->btn_link);
    Btn_Link_Langure_to_Set(ui->btn_link_bat);
    Btn_Link_Langure_to_Set(ui->btn_link_dlbox);
    Btn_Link_Langure_to_Set(ui->btn_link_disp_f210);
    Btn_Link_Langure_to_Set(ui->btn_link_f316);
    Btn_Link_Langure_to_Set(ui->btn_link_dl8000);

    // F210-电池修复
    ui->le_PD->setReadOnly(true);
    ui->le_SN->setReadOnly(true);
    ui->le_Mfrs->setReadOnly(true);
    ui->le_ManufacturerNo->setReadOnly(true);
    ui->sb_DesignCAP->setReadOnly(true);
    // F210
    Port_Function_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    ui->te_mtsn->setAttribute(Qt::WA_InputMethodEnabled, false);
    ui->te_mtsn->setStyleSheet(QString("border:1px solid #C0C0C0;"
                                       "border-style:solid;"
                                       "border-radius:0px;"
                                       "width:100px;"
                                       "height:20px;"
                                       "padding:0px;"));
    ui->te_file_write->setStyleSheet(QString("border:1px solid #C0C0C0;"
                                       "border-style:solid;"
                                       "border-radius:0px;"
                                       "width:100px;"
                                       "height:20px;"
                                       "padding:0px;"));
    ui->te_prin->setReadOnly(true);
    ui->te_prin->setTextColor(QColor(0,222,255));
    // F210-显示修复
    Btn_Lock_Or_Unlock_Disp_F210(DISP_BTN_LOCK_ALL);
    // 测试盒
    Dlbox_Btn_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    ui->te_mtsn_dlbox->setAttribute(Qt::WA_InputMethodEnabled, false);
    ui->te_mtsn_dlbox->setStyleSheet(QString("border:1px solid #C0C0C0;"
                                       "border-style:solid;"
                                       "border-radius:0px;"
                                       "width:100px;"
                                       "height:20px;"
                                       "padding:0px;"));
    ui->te_file_write_dlbox->setStyleSheet(QString("border:1px solid #C0C0C0;"
                                       "border-style:solid;"
                                       "border-radius:0px;"
                                       "width:100px;"
                                       "height:20px;"
                                       "padding:0px;"));
    ui->te_prin_dlbox->setReadOnly(true);
    // dlbox-动态配置
    Gui_Init_CFG();
    // 设置数据库
    SqlData_Cfg = QSqlDatabase::addDatabase("QSQLITE");
    SqlData_Cfg.setDatabaseName("QT5Config.dll");
    if(!SqlData_Cfg.open())
    {
        qDebug() << "SQL Open Failed!";
    }
    // 使数据库支持中文
    SqlData_Cfg.exec("SET NAMES 'Latin1'");
    // 创建 configure 表
    SqlData_Cfg.exec("create table configure (id int primary key, "
               "name varchar(35), type varchar(20), filename varchar(200), mode varchar(20), checked int)");
    SqlMode = new QSqlTableModel(this);
    SqlMode->setTable("configure");
    SqlMode->select(); // 设置编辑策略
    SqlMode->setEditStrategy(QSqlTableModel::OnManualSubmit);
    //
    Cfg_Sql_Init();

    // F316
    Port_F310_Get_File_Vers();
    Port_F316_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    ui->te_prin_dlbox->setReadOnly(true);

    // 获取F210文件版本
    Get_Check_Version_From_File();
    on_cbx_model_read_activated(0);
	
	// dl8000
	Port_dl8000_Function_Lock_Or_Unlock(DISP_BTN_LOCK_ALL);
    ui->te_mtsn_dl8000->setAttribute(Qt::WA_InputMethodEnabled, false);
    ui->te_mtsn_dl8000->setStyleSheet(QString("border:1px solid #C0C0C0;"
                                       "border-style:solid;"
                                       "border-radius:0px;"
                                       "width:100px;"
                                       "height:20px;"
                                       "padding:0px;"));
    ui->te_prin_dl8000->setReadOnly(true);
    ui->te_prin_dl8000->setTextColor(QColor(0,222,255));
}

// 标题窗口初始化
void MainWindow::Title_Widgt_Init()
{
    int count = MainBtns.count();
    for (int i = 0; i < count; ++i) {
        QToolButton *btn = (QToolButton *)MainBtns.at(i);
        btn->setCheckable(true);
        btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    }

    IconHelper::StyleColor styleColor;
    styleColor.position = "left";
    styleColor.iconSize = 18;
    styleColor.iconWidth = 35;
    styleColor.iconHeight = 25;
    styleColor.borderWidth = 4;
    styleColor.borderColor = borderColor;
    styleColor.setColor(normalBgColor, normalTextColor, darkBgColor, darkTextColor);
    IconHelper::setStyle(ui->wdg_left, MainBtns, iconsMain, styleColor);
}

//选择文件
void MainWindow::on_btn_file_write_clicked()
{
    bool ActiveStu = false;
    if(SyncTimer->isActive())
    {
        SyncTimer->stop();
        ActiveStu = true;
    }

    //对话框标题
    QString dlgTitle;
    if(LangureStu == 1)
    {
        dlgTitle="Select a file";
    }
    else
    {
        dlgTitle="选择一个文件";
    }
    //文件过滤器
    QString filter;
    if(LangureStu == 1)
    {
        filter="bin file(*.bin);;all file(*.*)";
    }
    else
    {
        filter="bin文件(*.bin);;所有文件(*.*)";
    }

    QString CfgDirName = CfgFile->value("OpenDir/Dir").toString();
    if(CfgDirName.isEmpty())
    {
        CfgDirName = FilePath;
    }
    QString sDestFileName=QFileDialog::getOpenFileName(this,dlgTitle,CfgDirName,filter);
    QString sSrcFileName = ui->te_file_write->toPlainText();
    if(sDestFileName.isEmpty())
    {
        sDestFileName = sSrcFileName;
    }
    else
    {
        //写ini
        CfgDirName = sDestFileName.mid(0,sDestFileName.lastIndexOf('/'));
        CfgFile->setValue("OpenDir/Dir",CfgDirName);
    }
    //显示目标文件路径
    ui->te_file_write->setText(sDestFileName);

    if(ActiveStu)
    {
        SyncTimer->start(TIMER_SYNC_TIME_OUT);
    }
}
//文件合法性校验
bool MainWindow::App_Check_Legal_FilePath(QString FileName, int CheckStu)
{
    if(FileName.isEmpty())
    {
        if(LangureStu == 1)
        {
            LangureStr = "The file cannot be empty!";
        }
        else
        {
            LangureStr = "文件不能为空!";
        }
        return false;
    }

    //判断文件是否存在
    bool FileStu;
    QFileInfo File(FileName);
    FileStu = File.isFile();
    if(!FileStu)
    {
        //文件不存在
        if(CheckStu == 0)
        {
            //
            if(LangureStu == 1)
            {
                LangureStr = "The write file does not exist, please enter the correct file name!";
            }
            else
            {
                LangureStr = "写入文件不存在,请输入正确的文件名!";
            }
            return false;
        }
        else
        {
            FileStu = File.isDir();
            if(FileStu)
            {
                //保存目录
                if(LangureStu == 1)
                {
                    LangureStr = "Write file does not exist!";
                }
                else
                {
                    LangureStr = "请输入保存文件名!";
                }
                return false;
            }
            else
            {
                //判断是否为文件，是则创建，否则提示文件错误，请重新输入
                QString pattern("^[^\\/:*?""<>|]+$");
                QRegExp rx(pattern);
                int match = FileName.indexOf(rx);
                if(match >= 0)
                {
                    if(LangureStu == 1)
                    {
                        LangureStr = "The saved file name is illegal. Please enter the correct file name!";
                    }
                    else
                    {
                        LangureStr = "保存文件名不合法，请输入正确的文件名!";
                    }
                    return false;
                }
            }
        }
    }
    return true;
}
//写入配置文件
void MainWindow::App_Write_FilePath_CfgFile(QString CfgVal,QString FileName)
{
    QString CfgDirName = FileName.mid(0,FileName.lastIndexOf('/'));
    CfgFile->setValue(CfgVal,CfgDirName);
}

//校验版本文件
void MainWindow::Get_Check_Version_From_File()
{
    QString VerFileName = FilePath + "/" + VersFileName;
    QFile VerFile(VerFileName);
    if(!VerFile.open(QIODevice::ReadOnly))
    {
        VerFile.close();
        return;
    }
    QByteArray FileData;
    FileData.clear();
    // 200*1024
    if(VerFile.size() < 0x00032000)
    {
        if(LangureStu == 1)
        {
            LangureStr = "Upgrade file error!";
        }
        else
        {
            LangureStr = "升级文件错误!";
        }
        InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
        VerFile.close();
        return ;
    }
    else
    {
        VerFile.seek(0x00032000);

#ifdef UPG_FILE_NAME_APP2
        if(VersFileName == UPG_FILE_NAME_APP2)
        {
            FileData.append(VerFile.read(4));
        }
        else
        {
            FileData.append(VerFile.read(6));
        }
#else
        FileData.append(VerFile.read(6));
#endif
    }

    VerFile.close();

    BinVersion = FileData;
}

//帮助
void MainWindow::ActHelp_to_Disp()
{

}

//复选框按钮组
void MainWindow::on_cbx_upg_clicked()
{
    bool CbxStu = ui->cbx_upg->isChecked();
    ui->btn_upg->setEnabled(CbxStu);
}

void MainWindow::Body_Load_Style(const QString &qssFile)
{
    //加载样式表
    QString qss;
    QFile file(qssFile);
    if (file.open(QFile::ReadOnly)) {
        //用QTextStream读取样式文件不用区分文件编码 带bom也行
        QStringList list;
        QTextStream in(&file);
        while (!in.atEnd()) {
            QString line;
            in >> line;
            list << line;
        }

        file.close();
        qss = list.join("\n");
        QString paletteColor = qss.mid(20, 7);
        ui->wdg_body->setPalette(QPalette(paletteColor));
        ui->wdg_body->setStyleSheet(qss);
		ui->pg_color->setPalette(QPalette(paletteColor));
        ui->pg_color->setStyleSheet(qss);
        ui->pg_disp_f210->setPalette(QPalette(paletteColor));
        ui->pg_disp_f210->setStyleSheet(qss);
        ui->pg_mtsn_dlbox->setPalette(QPalette(paletteColor));
        ui->pg_mtsn_dlbox->setStyleSheet(qss);
        ui->pg_mtsn_dl8000->setPalette(QPalette(paletteColor));
        ui->pg_mtsn_dl8000->setStyleSheet(qss);

        ui->wdg_bottom->setPalette(QPalette(paletteColor));
        ui->wdg_bottom->setStyleSheet(qss);
    }
}
void MainWindow::Title_Load_Style(const QString &qssFile)
{
    //加载样式表
    QString qss;
    QFile file(qssFile);
    if (file.open(QFile::ReadOnly)) {
        //用QTextStream读取样式文件不用区分文件编码 带bom也行
        QStringList list;
        QTextStream in(&file);
        while (!in.atEnd()) {
            QString line;
            in >> line;
            list << line;
        }

        file.close();
        qss = list.join("\n");
        QString paletteColor = qss.mid(20, 7);
        ui->wdg_title->setPalette(QPalette(paletteColor));
        ui->wdg_title->setStyleSheet(qss);
    }
}

//导入文件
void MainWindow::Menu_Option_Import_Upgrade_File()
{
    QWidget* wdg_import = new QWidget();
    QPushButton* btn_choose = new QPushButton(wdg_import);
    QPushButton* btn_import = new QPushButton(wdg_import);
    lbl_importstu = new QLabel(wdg_import);
    te_importfile = new QTextEdit(wdg_import);

    QGridLayout* glyt_importfile = new QGridLayout(wdg_import);

    wdg_import->setWindowFlags(Qt::WindowMinimizeButtonHint|Qt::WindowCloseButtonHint);
    wdg_import->resize(300,180);
    if(LangureStu == 1)
    {
        wdg_import->setWindowTitle("Import upgrade file");
        btn_choose->setText("Choose");
        btn_import->setText("Import");

        te_importfile->setPlaceholderText("Select path");
    }
    else
    {
        wdg_import->setWindowTitle("导入升级文件");
        btn_choose->setText("选择");
        btn_import->setText("导入");

        te_importfile->setPlaceholderText("选择路径");
    }

    glyt_importfile->addWidget(te_importfile,1,1);
    glyt_importfile->addWidget(btn_choose,1,2);
    glyt_importfile->addWidget(lbl_importstu,2,1);
    glyt_importfile->addWidget(btn_import,2,2);

    connect(btn_import, &QPushButton::clicked, this, &MainWindow::btn_import_file_clicked);
    connect(btn_choose, &QPushButton::clicked, this, &MainWindow::btn_choose_import_filepath_clicked);

    wdg_import->setWindowModality(Qt::ApplicationModal);
    wdg_import->show();
}
//选择文件路径
void MainWindow::btn_choose_import_filepath_clicked()
{
    bool ActiveStu = false;
    if(SyncTimer->isActive())
    {
        SyncTimer->stop();
        ActiveStu = true;
    }

    //对话框标题
    QString dlgTitle;
    if(LangureStu == 1)
    {
        dlgTitle="Select file path";
    }
    else
    {
        dlgTitle="选择文件路径";
    }
    //
    QString CfgDirName = CfgFile->value("OpenDir/Dir").toString();
    if(CfgDirName.isEmpty())
    {
        CfgDirName = FilePath;
    }
    QString sDestFileName=QFileDialog::getExistingDirectory(this,dlgTitle,CfgDirName);
    QString sSrcFileName = te_importfile->toPlainText();
    if(sDestFileName.isEmpty())
    {
        sDestFileName = sSrcFileName;
    }
    else
    {
        //写ini
        CfgDirName = sDestFileName.mid(0,sDestFileName.lastIndexOf('/'));
        CfgFile->setValue("OpenDir/Dir",CfgDirName);
    }
    //显示目标文件路径
    te_importfile->setText(sDestFileName);

    if(ActiveStu)
    {
        SyncTimer->start(TIMER_SYNC_TIME_OUT);
    }
}
//从文件路径中导入文件
void MainWindow::btn_import_file_clicked()
{
    lbl_importstu->setText("");
    //检测文件是否存在
    QString sDestFilePath = te_importfile->toPlainText();
    if(sDestFilePath.isEmpty())
    {
        return ;
    }

    //
    QString VerSrcFileName = FilePath + "/" + VersFileName;
    QString VerBakFileName = VerSrcFileName + ".bak";
    QString DevSrcFileName = FilePath + "/" + FpgaFileName;
    QString DevBakFileName = DevSrcFileName + ".bak";
    //判断文件是否存在
    bool AppFileStu;
    QString AppFileName = sDestFilePath+"/"+UPG_FILE_NAME_APP3;
    QFileInfo AppFile(AppFileName);
    AppFileStu = AppFile.isFile();
    bool DevFileStu;
    QString DevFileName = sDestFilePath+"/"+UPG_FILE_NAME_FPGA;
    QFileInfo DevFile(DevFileName);
    DevFileStu = DevFile.isFile();

    if(AppFileStu)
    {
        //复制文件至文件路径并更名为bak
        QFile::copy(AppFileName, VerBakFileName);
        //将源文件删除
        QFile::remove(VerSrcFileName);
        //将bak文件更名
        QFile::rename(VerBakFileName, VerSrcFileName);

        Get_Check_Version_From_File();
    }
    if(DevFileStu)
    {
        QFile::copy(DevFileName, DevBakFileName);
        QFile::remove(DevSrcFileName);
        QFile::rename(DevBakFileName, DevSrcFileName);
    }
    if(AppFileStu|DevFileStu)
    {
        lbl_importstu->setText("导入完成");
    }
}

void MainWindow::on_btn_ContactUs_clicked()
{
    CallWdg = new contactus(LangureStu);
    CallWdg->setStyleSheet("background:#FFFFFF");
    CallWdg->setWindowModality(Qt::ApplicationModal);
    CallWdg->setAttribute(Qt::WA_ShowModal,true);
    CallWdg->show();
}

//检查 选择机型 栏
bool MainWindow::Check_cbx_model_read_Must_Select(QComboBox* cbx_model_read, QTextEdit *te_prin)
{
    int Index = cbx_model_read->currentIndex();
    if(Index == 0)
    {
        if(LangureStu == 1)
        {
            LangureStr = "Please select the model";
        }
        else
        {
            LangureStr = "请选择机型";
        }
		InsertText(te_prin, LangureStr, DLBOX_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return false;
    }
    return true;
}

//F210-限制输入长度
void MainWindow::on_te_mtsn_textChanged()
{
    App_Te_Mtsn_Limit_InputLen(ui->te_mtsn);
}
//点亮盒子-限制输入长度
void MainWindow::on_te_mtsn_dlbox_textChanged()
{
    App_Te_Mtsn_Limit_InputLen(ui->te_mtsn_dlbox);
}
//dl8000-限制输入长度
void MainWindow::on_te_mtsn_dl8000_textChanged()
{
    App_Te_Mtsn_Limit_InputLen(ui->te_mtsn_dl8000);
}
// 限制输入长度
void MainWindow::App_Te_Mtsn_Limit_InputLen(QTextEdit* te_mtsn)
{
    QString TeContent = te_mtsn->toPlainText();
    int TeLength = TeContent.count();
#if 0
    int SetStu = 0;
    for(int icnt=0;icnt<TeLength;icnt++)
    {
        QString MtSN = TeContent.mid(icnt,1).toUpper();

        if(!((MtSN>='0'&&MtSN<='9') || (MtSN>='A'&&MtSN<='Z') || (MtSN=='+'||MtSN=='.')))
        {
            TeContent.replace(MtSN,"");
            icnt--;
            TeLength = TeContent.count();
            SetStu = 1;
        }
    }
    if(SetStu == 1)
        te_mtsn->setText(TeContent);
#endif
    int MaxLength = 44;
    if(TeLength > MaxLength)
    {
        int position = te_mtsn->textCursor().position();
        QTextCursor textCursor = te_mtsn->textCursor();
        TeContent.remove(position - (TeLength - MaxLength), TeLength - MaxLength);
        te_mtsn->setText(TeContent);
        textCursor.setPosition(position - (TeLength - MaxLength));
        te_mtsn->setTextCursor(textCursor);
    }
}

// 选择文件-文件名显示到单行编辑框
void MainWindow::App_ChooseFile_SavePath(QTextEdit* te_file, QString CfgDir)
{
    //对话框标题
    QString dlgTitle;
    if(LangureStu == 1)
    {
        dlgTitle="Select a file";
    }
    else
    {
        dlgTitle="选择一个文件";
    }
    //文件过滤器
    QString filter;
    if(LangureStu == 1)
    {
        filter="bin file(*.bin);;all file(*.*)";
    }
    else
    {
        filter="bin文件(*.bin);;所有文件(*.*)";
    }

    QString CfgDirName = CfgFile->value(CfgDir).toString();
    if(CfgDirName.isEmpty())
    {
        CfgDirName = FilePath;
    }
    QString sDestFileName= QFileDialog::getOpenFileName(this,dlgTitle,CfgDirName,filter);
    QString sSrcFileName = te_file->toPlainText();
    if(sDestFileName.isEmpty())
    {
        sDestFileName = sSrcFileName;
    }
    else
    {
        //写ini
        CfgDirName = sDestFileName.mid(0,sDestFileName.lastIndexOf('/'));
        CfgFile->setValue(CfgDir,CfgDirName);
    }
    //显示目标文件路径
    te_file->setText(sDestFileName);
}

// 选择文件-返回文件名
QString MainWindow::App_Btn_ChooseFile_GetPath(QString CfgDir)
{
    //对话框标题
    QString dlgTitle;
    if(LangureStu == 1)
    {
        dlgTitle="Select a file";
    }
    else
    {
        dlgTitle="选择一个文件";
    }
    //文件过滤器
    QString filter;
#ifdef QT_DEBUG
    if(LangureStu == 1)
    {
        filter="bin file(*.bin);;all file(*.*)";
    }
    else
    {
        filter="bin文件(*.bin);;所有文件(*.*)";
    }
#else
    if(LangureStu == 1)
    {
        filter="bin file(*.dat);;all file(*.*)";
    }
    else
    {
        filter="bin文件(*.dat);;所有文件(*.*)";
    }
#endif

    QString CfgDirName = CfgFile->value(CfgDir).toString();
    if(CfgDirName.isEmpty())
    {
        CfgDirName = FilePath;
    }
    QString sDestFileName = QFileDialog::getOpenFileName(this,dlgTitle,CfgDirName,filter);
    if(!sDestFileName.isEmpty())
    {
        //写ini
        CfgDirName = sDestFileName.mid(0,sDestFileName.lastIndexOf('/'));
        CfgFile->setValue(CfgDir,CfgDirName);
    }
    return sDestFileName;
}
// 选择路径-返回路径
QString MainWindow::App_Btn_ChoosePath_GetPath(QString CfgDir)
{
    //对话框标题
    QString dlgTitle;
    if(LangureStu == 1)
    {
        dlgTitle="Select a file Path";
    }
    else
    {
        dlgTitle="选择一个文件路径";
    }

    QString CfgDirName = CfgFile->value(CfgDir).toString();
    if(CfgDirName.isEmpty())
    {
        CfgDirName = FilePath;
    }
    QString sDestFilePath = QFileDialog::getExistingDirectory(this,dlgTitle,CfgDirName);
    if(!sDestFilePath.isEmpty())
    {
        //写ini
        CfgFile->setValue(CfgDir,sDestFilePath);
    }
    return sDestFilePath;
}

// 检查盖板码是否合法
bool MainWindow::App_Check_Legal_MtsnCode(QByteArray MtsnStr)
{
    if(MtsnStr.isEmpty())
    {
        if(LangureStu == 1)
        {
            LangureStr = "Burn MtSN cannot be empty!";
        }
        else
        {
            LangureStr = "写入盖板码不能为空!";
        }
        return false;
    }
    else if(44 != MtsnStr.size())
    {
        if(LangureStu == 1)
        {
            LangureStr = tr("MtSN length[%1] is incorrect, Pleasere-enter it!").arg(MtsnStr.size());
        }
        else
        {
            LangureStr = QString("盖板码长度[%1]有误，请重新输入!").arg(MtsnStr.size());
        }
        return false;
    }
    return true;
}

QStringList MainWindow::Check_new_device_detected(QStringList portStringList,QStringList PortList_Link,QString contains_str,int ConnectStu,QTextEdit* te_prin)
{
    QStringList PortList;
    PortList.clear();
    int icnt;
    for(icnt=0;icnt<portStringList.size();icnt++)
    {
        if(portStringList.at(icnt).contains(contains_str))
        {
            PortList.append(portStringList.at(icnt));
        }
    }
    if(PortList.size() > 0)
    {
        if(PortList_Link.size() != PortList.size())
        {
            if(LangureStu == 1)
            {
                LangureStr = "Device connection is detected, and the COM port can be connected:\n\t";
            }
            else
            {
                LangureStr = "检测到设备连接，可连接COM口:\n\t";
            }
            for (icnt=0;icnt<PortList.size();icnt++) {
                LangureStr += PortList.at(icnt) + "\n\t";
            }
            if(LangureStu == 1)
            {
                LangureStr += "Please select the COM port and click the \"Connect\" button at the bottom left";
            }
            else
            {
                LangureStr += "请选择COM口，单击左下方\"连接\"按钮";
            }
            if(ConnectStu != 1)
            {
                InsertText(te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_NORMAL);
            }
        }
    }
    return PortList;
}

void MainWindow::Check_null_device_detected(QStringList portStringList,QString contains_str,QTextEdit* te_prin)
{
    int icnt;
    for(icnt=0; icnt<portStringList.size(); icnt++)
    {
        if(portStringList.at(icnt).contains(contains_str))
        {
            break;
        }
    }
    if(icnt == portStringList.size())
    {
		if(LangureStu == 1)
		{
			LangureStr = "No device detected\n"
						 "\t1. Please connect the device\n";
		}
		else
		{
			LangureStr = "未检测到设备\n"
						 "\t1.请连接设备\n";
		}
		if("CH340" == contains_str)
		{
			if(LangureStu == 1)
			{
				LangureStr += "\t2. Please click the \"menu\"(three bars) button in the upper right corner - \"drive\" - \"Fxxx drive installation\"";
			}
			else
			{
				LangureStr += "\t2.请点击右上角\"菜单\"(三道杠)按钮-\"驱动\"-\"Fxxx驱动安装\"";
			}
		}
		else
		{
			if(LangureStu == 1)
			{
				LangureStr += "\t2. Please click the \"menu\"(three bars) button in the upper right corner - \"drive\" - \"DL400 drive installation\"";
			}
			else
			{
				LangureStr += "\t2.请点击右上角\"菜单\"(三道杠)按钮-\"驱动\"-\"DL400驱动安装\"";
			}
		}
        InsertText(te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
    }
}

bool MainWindow::Check_current_port(QString CurrentPort, int ConnectStu, QComboBox* cbx_port)
{
    if(ConnectStu == 1)
    {
        ConnectStu = 0;
        for (int icnt=0;icnt<portStringList.size();icnt++) {
            if(CurrentPort == portStringList.at(icnt))
            {
                if(CurrentPort != cbx_port->currentText())
                {
                    cbx_port->setCurrentText(CurrentPort);
                }
                ConnectStu = 1;
                break;
            }
        }
        if(ConnectStu == 0)
        {
            return false;
        }
    }
    return true;
}

void MainWindow::on_le_SN_textChanged(const QString &arg1)
{

}


//校验版本文件
QByteArray MainWindow::Get_Version_From_File(QString VersName, QTextEdit *TePrin, uint32_t OffAddr)
{
    QString VerFileName = FilePath + "/" + VersName;
    QFile VerFile(VerFileName);
    if(!VerFile.open(QIODevice::ReadOnly))
    {
        VerFile.close();
        return 0x00;
    }
    QByteArray FileData;
    FileData.clear();
    // 200*1024
    if(VerFile.size() < OffAddr)
    {
        if(LangureStu == 1)
        {
            LangureStr = "Upgrade file error!";
        }
        else
        {
            LangureStr = "升级文件错误!";
        }
        InsertText(TePrin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
        VerFile.close();
        return 0x00;
    }
    else
    {
        VerFile.seek(OffAddr);
        FileData.append(VerFile.read(6));
    }

    VerFile.close();

    return FileData;
}

void MainWindow::on_cbx_upg_dl8000_clicked()
{
    bool CbxStu = ui->cbx_upg_dl8000->isChecked();
    ui->btn_upg_dl8000->setEnabled(CbxStu);
}
